'use strict';
const fs = require('fs');
const path = require('path');
const moment = require('moment');
const { Op } = require("sequelize");
const xlsx = require('node-xlsx');

/**
 * 获取专利分页列表
 */
async function getPatentList(ctx) {
  let error = true;
  let rslt = null;
  let models = ctx.fs.dc.models;

  try {
    // 获取分页参数
    const { 
      page = 1, 
      pageSize = 10, 
      keyword = '', 
      sortField = 'id', 
      sortOrder = 'asc',
      patent_type = '',
      certificate_issue_date = '' 
    } = ctx.query;
    const offset = (page - 1) * pageSize;
    const limit = parseInt(pageSize);
    
    // 构建查询条件
    const where = {};
    if (keyword) {
      where[Op.or] = [
        { patent_name: { [Op.like]: `%${keyword}%` } },
        { application_number: { [Op.like]: `%${keyword}%` } },
        { patentee: { [Op.like]: `%${keyword}%` } },
        { case_number: { [Op.like]: `%${keyword}%` } },
        { first_inventor: { [Op.like]: `%${keyword}%` } }
      ];
    }
    
    // 添加专利类型筛选
    if (patent_type) {
      where.patent_type = patent_type;
    }
    
    // 添加下证发文日期筛选
    if (certificate_issue_date) {
      where.certificate_issue_date = certificate_issue_date;
    }
    
    // 获取总数
    const total = await models.PatentInfo.count({ where });
    
    // 排序方向
    let orderDirection = sortOrder.toUpperCase();
    // 将前端的ascend/descend转换为SQL需要的ASC/DESC
    if (orderDirection === 'ASCEND') {
      orderDirection = 'ASC';
    } else if (orderDirection === 'DESCEND') {
      orderDirection = 'DESC';
    }
    
    const order = [[sortField, orderDirection]];
    
    // 获取数据
    const patents = await models.PatentInfo.findAll({
      where,
      order,
      offset,
      limit
    });
    
    rslt = {
      data: patents,
      page: parseInt(page),
      pageSize: parseInt(pageSize),
      total
    };
    error = false;
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e}`);
  }

  if (error) {
    ctx.status = 400;
    ctx.body = { error: "GetPatentListError" };
  } else {
    ctx.status = 200;
    ctx.body = rslt;
  }
}

/**
 * 编辑专利信息
 */
async function editPatent(ctx) {
  let error = true;
  let rslt = null;
  let models = ctx.fs.dc.models;

  try {
    const { id } = ctx.params;
    const patentData = ctx.request.body;
    
    // 确保非必填字段有默认值
    if (patentData.changed_patentee === undefined || patentData.changed_patentee === null) {
      patentData.changed_patentee = '';
    }
    
    if (patentData.change_procedure_date === undefined || patentData.change_procedure_date === null) {
      patentData.change_procedure_date = null;
    }
    
    if (patentData.special_notes === undefined || patentData.special_notes === null) {
      patentData.special_notes = '';
    }
    
    if (patentData.related_development_project === undefined || patentData.related_development_project === null) {
      patentData.related_development_project = '';
    }
    
    // 如果是新增专利
    if (!id || id === 'new') {
      // 检查专利名称和申请号是否已存在
      const existingPatent = await models.PatentInfo.findOne({
        where: {
          patent_name: patentData.patent_name,
          application_number: patentData.application_number
        }
      });
      
      if (existingPatent) {
        error = true;
        rslt = { message: `${patentData.patent_name}已存在，请确认后重新提交` };
      } else {
        try {
          // 创建新专利
          const newPatent = await models.PatentInfo.create(patentData);
          if (newPatent && newPatent.id) {
            rslt = { data: newPatent, message: '专利创建成功' };
            error = false;
          } else {
            rslt = { message: '创建专利失败，请检查数据后重试' };
            error = true;
          }
        } catch (createErr) {
          ctx.fs.logger.error(`创建专利失败: ${createErr}`);
          rslt = { message: `创建专利失败: ${createErr.message}` };
          error = true;
        }
      }
    } else {
      // 检查是否存在冲突
      const existingPatent = await models.PatentInfo.findOne({
        where: {
          patent_name: patentData.patent_name,
          application_number: patentData.application_number,
          id: { [Op.ne]: id }
        }
      });
      
      if (existingPatent) {
        error = true;
        rslt = { message: `${patentData.patent_name}已存在，请确认后重新提交` };
      } else {
        try {
          // 更新专利信息
          const [updated] = await models.PatentInfo.update(patentData, {
            where: { id }
          });
          
          if (updated) {
            const updatedPatent = await models.PatentInfo.findByPk(id);
            rslt = { data: updatedPatent, message: '专利更新成功' };
            error = false;
          } else {
            rslt = { message: '未找到指定专利' };
          }
        } catch (updateErr) {
          ctx.fs.logger.error(`更新专利失败: ${updateErr}`);
          rslt = { message: `更新专利失败: ${updateErr.message}` };
          error = true;
        }
      }
    }
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e.stack || e}`);
    rslt = { message: `处理请求失败: ${e.message}`, error: true };
  }

  if (error) {
    ctx.status = 400;
    if (!rslt) {
      rslt = { error: true, message: "EditPatentError" };
    } else if (!rslt.error) {
      rslt.error = true;
    }
    ctx.body = rslt;
  } else {
    ctx.status = 200;
    ctx.body = rslt;
  }
}

/**
 * 删除专利
 */
async function deletePatent(ctx) {
  let error = true;
  let rslt = null;
  let models = ctx.fs.dc.models;

  try {
    const { id } = ctx.params;
    
    // 检查专利是否存在
    const patent = await models.PatentInfo.findByPk(id);
    
    if (!patent) {
      rslt = { message: '未找到指定专利' };
    } else {
      // 删除专利
      await models.PatentInfo.destroy({
        where: { id }
      });
      
      rslt = { message: '专利删除成功' };
      error = false;
    }
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e}`);
  }

  if (error) {
    ctx.status = 400;
    ctx.body = rslt || { error: "DeletePatentError" };
  } else {
    ctx.status = 200;
    ctx.body = rslt;
  }
}

/**
 * 导入专利数据
 */
async function importPatents(ctx) {
  let error = true;
  let rslt = null;
  let models = ctx.fs.dc.models;

  try {
    // 获取上传的文件
    const file = ctx.request.files.file;
    
    if (!file) {
      rslt = { message: '未找到上传文件' };
    } else {
      // 解析Excel文件
      const workSheetsFromFile = xlsx.parse(file.path);
      
      if (!workSheetsFromFile || !workSheetsFromFile[0] || !workSheetsFromFile[0].data) {
        rslt = { message: '无法解析文件内容' };
      } else {
        const sheetData = workSheetsFromFile[0].data;
        const headers = sheetData[0];
        
        // 验证必要的列是否存在
        const requiredColumns = ['专利名称', '专利申请号'];
        const missingColumns = requiredColumns.filter(col => !headers.includes(col));
        
        if (missingColumns.length > 0) {
          rslt = { message: `缺少必要的列: ${missingColumns.join(', ')}` };
        } else {
          // 映射Excel列到数据库字段
          const columnMap = {
            '序号': 'id',
            '我司案号': 'case_number',
            '专利名称': 'patent_name',
            '专利申请号': 'application_number',
            '专利类型': 'patent_type',
            '技术交底书收集时间': 'disclosure_collection_date',
            '受理发文': 'acceptance_notice_date',
            '授权发文': 'grant_notice_date',
            '下证发文': 'certificate_issue_date',
            '无效日期': 'invalidation_date',
            '代理机构处理时间': 'agency_process_date',
            '国知局下证处理闭环时间': 'cnipa_process_date',
            '专利状态': 'patent_status',
            '是否走快审通道': 'fast_track',
            '专利权人': 'patentee',
            '发明人': 'inventors',
            '第一发明人': 'first_inventor',
            '来源部门': 'department',
            '关联产品': 'related_product',
            '关联立项/课题': 'related_project',
            '防御型/攻击型': 'strategy_type',
            '是否为核心': 'is_core',
            '核心分数': 'core_score',
            '原始交底书名称': 'original_disclosure_name',
            '代理机构': 'agency',
            '负责人': 'manager',
            '代理案号': 'agency_case_number'
          };
          
          // 找出列索引映射
          const columnIndexMap = {};
          headers.forEach((header, index) => {
            if (columnMap[header]) {
              columnIndexMap[columnMap[header]] = index;
            }
          });
          
          // 准备导入数据
          const patents = [];
          const errors = [];
          
          // 从第二行开始遍历数据行
          for (let i = 1; i < sheetData.length; i++) {
            const row = sheetData[i];
            if (!row || row.length === 0 || !row[columnIndexMap.patent_name]) {
              continue; // 跳过空行或没有专利名称的行
            }
            
            const patentData = {};
            
            // 映射Excel数据到对象
            Object.keys(columnIndexMap).forEach(field => {
              const colIndex = columnIndexMap[field];
              let value = row[colIndex];
              
              // 处理特殊字段
              if (field === 'fast_track') {
                value = value === '是' ? true : (value === '否' ? false : null);
              } else if (field === 'is_core') {
                value = value === '是' ? true : (value === '否' ? false : null);
              } else if (field.includes('date')) {
                // 处理日期
                if (value) {
                  // 尝试将Excel日期转换为标准格式
                  if (typeof value === 'number') {
                    // Excel日期是从1900-01-01开始的天数
                    const excelEpoch = new Date(1900, 0, -1).getTime();
                    const daysSinceExcelEpoch = value;
                    const millisecondsSinceExcelEpoch = daysSinceExcelEpoch * 24 * 60 * 60 * 1000;
                    value = new Date(excelEpoch + millisecondsSinceExcelEpoch);
                    value = moment(value).format('YYYY-MM-DD');
                  } else if (typeof value === 'string') {
                    // 尝试解析字符串日期
                    value = moment(value).isValid() ? moment(value).format('YYYY-MM-DD') : null;
                  }
                } else {
                  value = null;
                }
              }
              
              patentData[field] = value;
            });
            
            // 检查是否存在重复
            const existingPatent = await models.PatentInfo.findOne({
              where: {
                patent_name: patentData.patent_name,
                application_number: patentData.application_number
              }
            });
            
            if (existingPatent) {
              errors.push(`第${i+1}行: ${patentData.patent_name}已存在，请确认后重新导入`);
            } else {
              patents.push(patentData);
            }
          }
          
          // 如果有错误但还有可导入的数据，继续导入
          if (errors.length > 0 && patents.length === 0) {
            rslt = { message: '导入失败', errors };
          } else {
            // 批量创建专利
            if (patents.length > 0) {
              await models.PatentInfo.bulkCreate(patents);
            }
            
            rslt = {
              message: '导入完成',
              success: patents.length,
              errors: errors.length > 0 ? errors : null
            };
            error = false;
          }
        }
      }
      
      // 删除临时文件
      try {
        fs.unlinkSync(file.path);
      } catch (e) {
        ctx.fs.logger.error(`Failed to delete temp file: ${file.path}, error: ${e}`);
      }
    }
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e}`);
  }

  if (error) {
    ctx.status = 400;
    ctx.body = rslt || { error: "ImportPatentsError" };
  } else {
    ctx.status = 200;
    ctx.body = rslt;
  }
}

/**
 * 变更专利权人
 */
async function changePatentee(ctx) {
  let error = true;
  let rslt = null;
  let models = ctx.fs.dc.models;

  try {
    const { id } = ctx.params;
    const { changed_patentee, change_procedure_date } = ctx.request.body;
    
    // 验证必填字段
    if (!changed_patentee || !change_procedure_date) {
      rslt = { message: '变更后专利权人和变更手续合格日期为必填项' };
    } else {
      // 检查专利是否存在
      const patent = await models.PatentInfo.findByPk(id);
      
      if (!patent) {
        rslt = { message: '未找到指定专利' };
      } else {
        // 更新专利权人信息
        const [updated] = await models.PatentInfo.update({
          changed_patentee,
          change_procedure_date
        }, {
          where: { id }
        });
        
        if (updated) {
          const updatedPatent = await models.PatentInfo.findByPk(id);
          rslt = { data: updatedPatent, message: '专利权人变更成功' };
          error = false;
        } else {
          rslt = { message: '专利权人变更失败' };
        }
      }
    }
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e}`);
  }

  if (error) {
    ctx.status = 400;
    ctx.body = rslt || { error: "ChangePatenteeError" };
  } else {
    ctx.status = 200;
    ctx.body = rslt;
  }
}

/**
 * 导出专利数据
 */
async function exportPatents(ctx) {
  let error = true;
  let models = ctx.fs.dc.models;

  try {
    // 获取查询参数
    const { 
      keyword = '',
      patent_type = '',
      certificate_issue_date = '',
      ids = ''
    } = ctx.query;

    // 构建查询条件
    const where = {};
    if (keyword) {
      where[Op.or] = [
        { patent_name: { [Op.like]: `%${keyword}%` } },
        { application_number: { [Op.like]: `%${keyword}%` } },
        { patentee: { [Op.like]: `%${keyword}%` } },
        { case_number: { [Op.like]: `%${keyword}%` } },
        { first_inventor: { [Op.like]: `%${keyword}%` } }
      ];
    }
    
    // 添加专利类型筛选
    if (patent_type) {
      where.patent_type = patent_type;
    }
    
    // 添加下证发文日期筛选
    if (certificate_issue_date) {
      where.certificate_issue_date = certificate_issue_date;
    }
    
    // 如果指定了ID列表，则只导出这些ID的数据
    if (ids) {
      const idList = ids.split(',').map(id => parseInt(id, 10)).filter(id => !isNaN(id));
      if (idList.length > 0) {
        where.id = { [Op.in]: idList };
      }
    }
    
    // 获取数据
    const patents = await models.PatentInfo.findAll({ where });
    
    // 定义Excel列头
    const headers = [
      '序号', '我司案号', '专利名称', '专利申请号', '专利类型', 
      '技术交底书收集时间', '受理发文', '授权发文', '下证发文', '无效日期',
      '代理机构处理时间', '国知局下证处理闭环时间', '专利状态', '是否走快审通道',
      '专利权人', '变更后专利权人', '变更手续合格日期', '发明人', '第一发明人',
      '来源部门', '关联产品', '关联立项/课题', '防御型/攻击型', '是否为核心',
      '核心分数', '原始交底书名称', '代理机构', '负责人', '代理案号',
      '特殊事项备注', '（发展部）关联课题/项目'
    ];
    
    // 准备Excel数据
    const excelData = [];
    excelData.push(headers); // 添加表头
    
    // 添加数据行
    patents.forEach((patent, index) => {
      // 处理日期格式
      const formatDate = (dateStr) => {
        if (!dateStr) return '';
        const date = moment(dateStr);
        return date.isValid() ? date.format('YYYY-MM-DD') : '';
      };

      const row = [
        index + 1, // 序号
        patent.case_number || '',
        patent.patent_name || '',
        patent.application_number || '',
        patent.patent_type || '',
        formatDate(patent.disclosure_collection_date),
        formatDate(patent.acceptance_notice_date),
        formatDate(patent.grant_notice_date),
        formatDate(patent.certificate_issue_date),
        formatDate(patent.invalidation_date),
        formatDate(patent.agency_process_date),
        formatDate(patent.cnipa_process_date),
        patent.patent_status || '',
        patent.fast_track ? '是' : '否',
        patent.patentee || '',
        patent.changed_patentee || '',
        formatDate(patent.change_procedure_date),
        patent.inventors || '',
        patent.first_inventor || '',
        patent.department || '',
        patent.related_product || '',
        patent.related_project || '',
        patent.strategy_type || '',
        patent.is_core ? '是' : '否',
        patent.core_score || '',
        patent.original_disclosure_name || '',
        patent.agency || '',
        patent.manager || '',
        patent.agency_case_number || '',
        patent.special_notes || '',
        patent.related_development_project || ''
      ];
      
      excelData.push(row);
    });
    
    // 生成Excel文件
    const buffer = xlsx.build([{ name: '专利列表', data: excelData }]);
    
    // 生成符合HTTP标准的文件名
    const timestamp = moment().format('YYYYMMDD_HHmmss');
    const filename = encodeURIComponent(`专利列表_${timestamp}.xlsx`);
    
    // 设置响应头
    ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    ctx.set('Content-Disposition', `attachment; filename=${filename}`);
    
    // 发送文件
    ctx.body = buffer;
    error = false;
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e.stack || e}`);
    ctx.status = 400;
    ctx.body = { error: "ExportPatentsError", message: e.message };
    return; // 提前返回，避免重复设置状态
  }

  // 只有没有发生错误时才会到达这里
  if (error) {
    ctx.status = 400;
    ctx.body = { error: "ExportPatentsError" };
  }
}

/**
 * 获取专利导入模板
 */
async function getPatentTemplate(ctx) {
  let error = true;

  try {
    // 定义Excel列头
    const headers = [
      '序号', '我司案号', '专利名称', '专利申请号', '专利类型', 
      '技术交底书收集时间', '受理发文', '授权发文', '下证发文', '无效日期',
      '代理机构处理时间', '国知局下证处理闭环时间', '专利状态', '是否走快审通道',
      '专利权人', '变更后专利权人', '变更手续合格日期', '发明人', '第一发明人',
      '来源部门', '关联产品', '关联立项/课题', '防御型/攻击型', '是否为核心',
      '核心分数', '原始交底书名称', '代理机构', '负责人', '代理案号',
      '特殊事项备注', '（发展部）关联课题/项目'
    ];
    
    // 添加示例数据
    const exampleRow = [
      1, 'CAS2023001', '一种通信系统的实现方法', 'CN202311111111.1', '发明专利',
      '2023-01-01', '2023-02-01', '2023-05-01', '2023-07-01', '2043-07-01',
      '2023-01-15', '2023-06-01', '授权', '是',
      '公司名称', '', '', '张三,李四,王五', '张三',
      '研发部', '产品A', '项目B', '防御型', '是',
      '85', '通信系统技术交底', '代理机构A', '张经理', 'AG2023001',
      '', '研发项目C'
    ];
    
    // 准备Excel数据
    const excelData = [];
    excelData.push(headers); // 添加表头
    excelData.push(exampleRow); // 添加示例数据行
    
    // 生成Excel文件
    const buffer = xlsx.build([{ name: '专利导入模板', data: excelData }]);
    
    // 设置响应头
    ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    ctx.set('Content-Disposition', 'attachment; filename=专利导入模板.xlsx');
    
    // 发送文件
    ctx.body = buffer;
    error = false;
  } catch (e) {
    ctx.fs.logger.error(`path: ${ctx.path}, error: ${e}`);
  }

  if (error) {
    ctx.status = 400;
    ctx.body = { error: "GetPatentTemplateError" };
  }
}

module.exports = {
  getPatentList,
  editPatent,
  deletePatent,
  importPatents,
  changePatentee,
  exportPatents,
  getPatentTemplate
}; 